/*
 * wk_hash.c
 *
 *  Created on: 2012-3-8
 *      Author: tianmax
 */

#include <stdio.h>
#include <stdlib.h>
#include "wk_hash.h"

/****************************************************/
extern WHash* wk_hash_init(wsize_t table_size,
		wk_hash_func hash_func,wk_element_comp comp){

	/*参数检查*/
//	if(!hash_func || !comp) return NULL;
	WHash* hash=(WHash*)calloc(1,sizeof(WHash));
	if(hash==NULL)
		return NULL;

	hash->hash=(WSList**)calloc(table_size,sizeof(WSList*));
	if(hash->hash==NULL)
		return NULL;

	hash->table_size=table_size;
	hash->comp=comp;
	hash->hash_func=hash_func;

	int i;
	for(i=0;i<table_size;i++){
		hash->hash[i]=wk_slist_init(hash->comp);
		if(hash->hash[i]==NULL){
			i--;
			/*释放已经初始化的链表*/
			for(;i>=0;i--){
				wk_slist_destroy(hash->hash[i]);
				hash->hash[i]=NULL;
			}

			/*释放函数主体*/
			free(hash->hash);
			hash->hash=NULL;

			/*释放数据结构的结构体*/
			free(hash);
			hash=NULL;

			/*返回NULL*/
			return NULL;

		}
	}
	/*将哈希主体的所有元素初始化完毕*/

	return hash;
}

extern void wk_hash_destroy(WHash* hash){

	/*参数检查*/
	if(hash==NULL){
		return;
	}else{
		if(hash->hash==NULL){
			free(hash);
			hash=NULL;
			return;
		}else{
			/*建立一些变量*/
			int i;
			/*1.释放所有的链表*/
			for(i=0;i<hash->table_size;i++){
				wk_slist_destroy(hash->hash[i]);
				hash->hash[i]=NULL;
			}
			/*2.释放函数主体*/
			free(hash->hash);
			hash->hash=NULL;

			/*3.释放数据结构的结构体*/
			free(hash);
			hash=NULL;
	}
	}
}
/*******************************************************************/
/*设置哈希函数*/
extern int wk_hash_setHashFunc(WHash* hash,wk_hash_func hash_func){
	if(!hash->hash) return -1;
	hash->hash_func=hash_func;
	return 0;
}
/*设置元素比较器*/
extern int wk_hash_setComp(WHash* hash,wk_element_comp comp){
	if(!hash->hash) return -1;
	hash->comp=comp;
	return 0;
}
/****************************************************/
/**
 * 清空哈希表中的所有内容，使其成为一个空哈希表
 */
extern int wk_hash_clean(WHash* hash){
//参数检查
	if(hash==NULL){
		return -1;
	}
//初始化函数环境
	int i=0;
	int ret=0;
//函数业务逻辑
	for(i=0;i<hash->table_size;i++){
		ret=wk_slist_clean(hash->hash[i]);
		if(ret<0){
			break;
		}
	}
	return ret;
}
/****************************************************/
extern WPElement wk_hash_value(WHash* hash,WPElement data){

	return wk_hash_find(hash,data);
}
/****************************************************/
/*允许插入为NULL的数据*/
extern int wk_hash_insert(WHash* hash,WPElement data){
//参数检查
	if(hash==NULL){
		return -1;
	}
	if(hash->hash_func==NULL){
		return -1;
	}
//初始化函数环境
	//要插入位置下标
	size_t index=0;
	//返回值
	int ret=0;
//函数业务逻辑开始
	//1.通过hash函数，计算出要插入的下标
	index=hash->hash_func(data,hash->table_size);
	//插入到对应位置的List中
	ret=wk_slist_append(hash->hash[index],data);
	if(ret<0){
		return ret;
	}
//函数业务逻辑结束，释放资源
//返回
	return 0;
}
/****************************************************/
extern int wk_hash_remove(WHash* hash,WPElement data){
//参数检查
	if(hash==NULL){
		return -1;
	}
	if(hash->hash_func==NULL){
		return -1;
	}
//初始化函数环境
	//要插入位置下标
	size_t index=0;
	//返回值
	int ret=0;
//函数业务逻辑开始
	//1.通过hash函数，计算出要插入的下标
	index=hash->hash_func(data,hash->table_size);
	if((ret=wk_slist_count(hash->hash[index]))<0){
		return ret;
	}else{
		ret=wk_slist_remove(hash->hash[index],data);
	}
//函数业务逻辑结束，释放资源
//返回
	return ret;
}
/****************************************************/
extern WPElement wk_hash_find(WHash* hash,WPElement data){
//参数检查
	if(hash==NULL){
		return NULL;
	}
	if(hash->hash_func==NULL){
		return NULL;
	}
//初始化函数环境
	//要插入位置下标
	size_t index=0;
	//返回值
	WPElement retp=NULL;
//函数业务逻辑开始
	//1.通过hash函数，计算出要插入的下标
	index=hash->hash_func(data,hash->table_size);
	//2.查找
	retp=wk_slist_find(hash->hash[index],data);

//函数业务逻辑结束，释放资源
//返回
	return retp;
}
/*****************************************************/
/**
 * 统计当前哈希表中存储数据的数量
 */
extern wlong_t wk_hash_count(WHash* hash){
	/*参数检查*/
	if(!hash) return -1;
	/*初始化函数环境*/
	wlong_t lret=0;
	int i=0;
	/*函数业务逻辑*/
	for(i=0;i<hash->table_size;i++){
		wlong_t tmpsize=wk_slist_count(hash->hash[i]);
		if(tmpsize<0){
			return -1;
		}
		lret+=tmpsize;
	}

	return lret;
}
/****************************************************/
/**
 * 遍历哈希表
 */
extern void wk_hash_iterate(WHash* hash,wk_element_iterate_do iterate_do,void* ctx){

	//参数检查
		if(hash==NULL){
			return;
		}
	//初始化函数环境
		int i=0;
	//函数业务逻辑开始
		for(i=0;i<hash->table_size;i++){
			wk_slist_iterate(hash->hash[i],iterate_do,ctx);
		}
	//函数业务逻辑结束，释放资源
	//返回
}
